home *** CD-ROM | disk | FTP | other *** search
- /* Support for opening a tek4010 window from napsaterm on the Amiga. This
- option is enabled if the symbol TEKTRONICS is defined at compile time. */
-
- /* tek4010.c is by RKNOP, Robert Knop, rknop@mop.caltech.edu */
-
- /* tek4010 version 1.4 beta */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "amiga.h"
- #include "nifty.h"
- #include "napsaprefs.h"
- #include "wimp.h"
- #include "nio.h"
- #include "ascii_ctrl.h"
- #include <graphics/displayinfo.h>
- #include <graphics/gfxmacros.h>
- #include <intuition/screens.h>
- #include <libraries/asl.h>
- #include <libraries/gadtools.h>
- #include <proto/asl.h>
- #include <proto/diskfont.h>
- #include <proto/intuition.h>
- #include <proto/gadtools.h>
- #include <proto/graphics.h>
- #include <proto/keymap.h>
- #include <proto/console.h>
- /*
- #include <proto/exec.h>
- */
-
- #ifdef TEKTRONICS
- /*#echo "Compiling tek4010 unit"*/
-
- /********** NOTE -- This is a hack I'm using to get bloody napsaterm to link
- with the debugger! *************/
-
- const UBYTE _DevName[]="Rob's Hack";
-
- /**************** End of NOTE ***************************************************/
-
- /* Local functions not needed by the outside */
-
- int opentekwin(void);
- void calctekwinsize(void);
- void newtekfont(void);
- int decode_integer(char);
- void Safe_Move(struct RastPort *,WORD,WORD);
- void Safe_Draw(struct RastPort *,WORD,WORD);
- void Safe_Rect(struct RastPort *,WORD,WORD);
- void scrtotek(void);
- void graph_clear(void);
- void setdrawmode(ULONG mode,WORD noerase);
- void redrawtek(void);
- void gin_mode_toggle(struct MenuItem *);
- void ginmouse(struct IntuiMessage *msg);
- void ginkeys(struct IntuiMessage *);
- void sendreport(WORD,WORD,char);
- void menu_close(void);
- void tekmenu(struct IntuiMessage *);
- void chk_active(struct MenuItem *);
- void chk_front(struct MenuItem *);
-
- #define FULLWIDTH 4096
- #define FULLHEIGHT 3120
- #define BUFFERSIZE 65536
-
- int tekmode=0; /*Global variable, 1 if tek window is current window*/
- int bypassmode=0;
- static int fullcursor=0;
- static char eolstring[]="\015\0\0"; /*End of report string <CR>*/
- static mode=TEK_ALPHA;
- static int buffermode=0;
- #define DEF_ACTIVE CHECKED
- #define DEF_FRONT CHECKED
- static int activateonswitch=DEF_ACTIVE;
- static int forwardonswitch=DEF_FRONT;
-
- extern struct KeyMap *default_map; /* In keymap.c */
- extern struct KeyMap *used_map; /* In keymap.c */
- extern struct IOStdReq consolereq; /* In keymap.c */
- #define ConsoleDevice (consolereq.io_Device)
-
- extern struct Window *w; /*vt100 window in wimp.c*/
- struct Window *tekwindow=NULL;
- static WORD maxx,maxy,minx,miny;
- long tekwinmask=0;
- static int winw,winh;
- static int tekwidth=FULLWIDTH,tekheight=FULLHEIGHT,tekleft=0,tekbot=0;
- static Point Aspect;
- static char *tekbuffer=NULL;
- static char *startbuffer,*endbuffer;
- #define ENDCHECK if (endbuffer<tekbuffer) endbuffer+=BUFFERSIZE;
- static char tektitle[80];
-
- /* Text/Font information */
-
- static struct TextAttr deftekattr={"topaz.font",8,0x00,0x00};
- static struct TextAttr tekattr;
- static struct TextFont *tekfont;
-
- /*Tektronics drawing variables*/
-
- static int last_mode;
- static int esc_mode=0;
- static int first_vector=1,incr_pen_down=0;
- static WORD increment=4; /*Move in incr mode*/
- static WORD lastx,lasty; /*Previous position in screen coords*/
- static WORD tekx,teky; /*Prev. pos. in tek coords*/
- static UWORD lyok; /* Flag, is last y out of bounds*/
- static char HiY,Extra,LoY,HiX,LoX; /*Tektronics position*/
- static char LoYorExtra=0; /*temp storage for ambiguity*/
- static char LastTag; /*Tag bits of last vector byte*/
-
- /*********************************************************************************/
- /* Open the tek4010 window on the napsaterm public screen */
- /* By nature, it opens to the full size of the screen sans the title bar. */
- /*********************************************************************************/
-
- static struct NewMenu tekmenus[]=
- { {NM_TITLE, "TEK4010", 0, 0, 0, 0,},
- { NM_ITEM, "To VT102", "T", 0, 0, tek_vt100,},
- { NM_ITEM, "To Tek", "G", 0, 0, vt100_tek,},
- { NM_ITEM, "Graph Clear", "C", 0, 0, graph_clear,},
- { NM_ITEM, "Redraw", "R", 0, 0, redrawtek,},
- { NM_ITEM, "Set Font...", "F", 0, 0, newtekfont,},
- { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
- { NM_ITEM, "Close", "Q", 0, 0, menu_close,},
- {NM_TITLE, "Config", 0, 0, 0, 0,},
- { NM_ITEM, "Activate Windows",0,MENUTOGGLE|CHECKIT|DEF_ACTIVE,0,chk_active,},
- { NM_ITEM, "Front Windows", 0,MENUTOGGLE|CHECKIT|DEF_FRONT,0,chk_front,},
- {NM_TITLE, "GIN Cursor", 0, 0, 0, 0,},
- { NM_ITEM, "Cursor On", 0,MENUTOGGLE|CHECKIT,0,gin_mode_toggle,},
- #define CURSOR_MENUNUM 2
- { NM_END, NULL, 0, 0, 0, 0,},
- };
- static APTR visinfo;
- static struct Menu *menuStrip;
-
- int opentekwin(void)
- { ULONG modeID;
- struct DisplayInfo di;
- struct Screen *s;
- char *pubscname;
- static int first=1; /*Flag, first call to opentekwin*/
-
- if (!(tekbuffer=AllocMem(BUFFERSIZE,MEMF_PUBLIC))) return(0);
- startbuffer=endbuffer=tekbuffer;
-
- pubscname=np.pubscname;
- s=LockPubScreen(pubscname); /*Try to lock the public screen*/
- if (!s && pubscname) s=LockPubScreen(pubscname=NULL); /*Try def. pub scr*/
- if (!s) /*Complete and utter failure*/
- { FreeMem(tekbuffer,65536);
- return(0);
- }
-
- modeID=GetVPModeID(&s->ViewPort);
- if (!GetDisplayInfoData(NULL,(UBYTE *)&di,sizeof(di),DTAG_DISP,modeID))
- { FreeMem(tekbuffer,65536);
- UnlockPubScreen(NULL,s);
- return(0);
- }
- Aspect.x=di.Resolution.x; Aspect.y=di.Resolution.y;
-
- sprintf(tektitle,"%s (TEK-4010)",np.title ? np.title : ProgName);
- tekwindow=
- OpenWindowTags(NULL, WA_PubScreen,s , WA_Left,0 , WA_Top,s->BarHeight ,
- WA_Width,s->Width , WA_Height,s->Height-s->BarHeight ,
- WA_MinWidth,70 , WA_MinHeight, 30 ,
- WA_MaxWidth,s->Width , WA_MaxHeight,s->Height ,
- WA_ScreenTitle,ProgName , WA_Title,tektitle ,
- WA_Flags,WFLG_SMART_REFRESH | WFLG_CLOSEGADGET |
- WFLG_DEPTHGADGET | WFLG_DRAGBAR |
- WFLG_NOCAREREFRESH | WFLG_ACTIVATE |
- WFLG_SIZEGADGET ,
- WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE |
- IDCMP_MENUPICK | IDCMP_RAWKEY ,
- TAG_DONE);
- UnlockPubScreen(NULL,s);
-
- if (!tekwindow) return(0);
- visinfo=GetVisualInfo(s,TAG_END); /*Check ret val?*/
- menuStrip=CreateMenus(tekmenus,TAG_END); /*Check return?*/
- LayoutMenus(menuStrip,visinfo,TAG_END); /*Check return?*/
- SetMenuStrip(tekwindow,menuStrip); /*Check return?*/
-
- tekwinmask=1<<tekwindow->UserPort->mp_SigBit;
- calctekwinsize();
- setdrawmode(JAM1,1);
- if (first)
- { tekattr=deftekattr; /*Set to default the first time only*/
- first=0;
- }
- if (!(tekfont=OpenDiskFont(&tekattr)))
- { tekattr=deftekattr; /*Failed to open font, open topaz 8*/
- tekfont=OpenDiskFont(&tekattr);
- }
- SetFont(tekwindow->RPort,tekfont); /*Set font for alpha mode*/
- graph_clear(); /*Always start with cleared graphics screen*/
- return(1);
- }
-
- /******************************************************************************/
- /* closetekwin() -- close the tek window, quit tek terminal mode */
- /******************************************************************************/
-
- void closetekwin(void)
- { struct Message *msg;
-
- if (!tekwindow) return;
- tekmode=0;
- tekwinmask=0;
- while (msg=GetMsg(tekwindow->UserPort)) /*Clean messages out of user port*/
- ReplyMsg(msg);
- ClearMenuStrip(tekwindow); /*Get rid of those GadTools menus*/
- FreeMenus(menuStrip);
- FreeVisualInfo(visinfo);
- CloseWindow(tekwindow);
- tekwindow=NULL; /*Make sure we know there is no tekwindow*/
- CloseFont(tekfont); /*Close the font, we no longer need it*/
- FreeMem(tekbuffer,65536);
- }
-
- /******************************************************************************/
- /* calctekwinsize() -- load winw and winh according to proper Tek screen size */
- /******************************************************************************/
-
- void calctekwinsize(void)
- { int w,h;
-
- minx=tekwindow->BorderLeft;
- maxx=tekwindow->Width-tekwindow->BorderRight-1;
- w=maxx-minx;
- miny=tekwindow->BorderTop;
- maxy=tekwindow->Height-tekwindow->BorderBottom-1;
- h=maxy-miny;
-
- winh=h;
- winw=(tekwidth*winh*Aspect.y) / (tekheight*Aspect.x);
- if (winw>w)
- { winw=w;
- winh=(tekheight*winw*Aspect.x) / (tekwidth*Aspect.y);
- }
- }
-
- /*****************************************************************************/
- /* Put up the ASL font requester to get a new font */
- /*****************************************************************************/
-
- void newtekfont(void)
- { struct FontRequester *req;
- struct TextAttr oldattr;
-
- if (!tekwindow) return;
- if (!(req=(struct FontRequester *)AllocAslRequestTags(
- ASL_FontRequest,ASL_FontName,(ULONG)tekattr.ta_Name,
- ASL_FontHeight,(ULONG)tekattr.ta_YSize,
- ASL_FuncFlags,FONF_FIXEDWIDTH,ASL_Window,tekwindow,TAG_END)))
- return;
- if (AslRequest(req,NULL))
- { oldattr=tekattr;
- tekattr=req->fo_Attr;
- CloseFont(tekfont); /*Close the old font*/
- if (!(tekfont=OpenDiskFont(&tekattr))) /*Try to open new font*/
- { tekattr=oldattr;
- if (!(tekfont=OpenDiskFont(&tekattr))) /*If fail, go back to old*/
- { tekattr=deftekattr;
- tekfont=OpenDiskFont(&tekattr); /*If _that_ fails, go to topaz/8*/
- }
- }
- SetFont(tekwindow->RPort,tekfont);
- }
- FreeAslRequest(req);
- }
- /*****************************************************************************/
- /* Set tektronics mode */
- /*****************************************************************************/
-
- void set_tekmode(unsigned short newmode)
- { struct RastPort *rp;
- WORD x,y;
-
- rp=tekwindow->RPort;
- if ((mode=newmode)==TEK_ALPHA) /*Do some bounds checking*/
- { if (!(rp->cp_x > (x=tekwindow->Width - tekwindow->BorderRight -
- tekfont->tf_XSize)))
- x=rp->cp_x;
- if (!(rp->cp_y < (y=tekwindow->BorderTop + tekfont->tf_Baseline)))
- y=rp->cp_y;
- Move(rp,x,y); /*Now we know it is safe to render a letter*/
- }
- }
-
- /****************************************************************************/
- /* Switch from vt100 mode to tek mode without clearing the tek screen */
- /****************************************************************************/
-
- void vt100_tek(void)
- {
- if (!tekwindow)
- { if (!opentekwin()) return;
- }
- if (activateonswitch) ActivateWindow(tekwindow);
- if (forwardonswitch) WindowToFront(tekwindow);
- tekmode=1;
- }
-
- /*******************************************************************************/
- /* Switch from tek mode to vt100 mode */
- /*******************************************************************************/
-
- void tek_vt100(void)
- {
- if (activateonswitch) ActivateWindow(w);
- if (forwardonswitch) WindowToFront(w);
- tekmode=0;
- }
-
- /******************************************************************************/
- /* graph_clear() -- clear the graphics screen and the tek buffer */
- /******************************************************************************/
-
- void graph_clear(void)
- { WORD xscr,yscr;
-
- startbuffer=endbuffer=tekbuffer;
- SetAPen(tekwindow->RPort,0);
- RectFill(tekwindow->RPort,tekwindow->BorderLeft,tekwindow->BorderTop,
- tekwindow->Width-1-tekwindow->BorderRight,
- tekwindow->Height-1-tekwindow->BorderBottom);
- HiY=Extra=LoY=HiX=LoX=LoYorExtra=(char)0; /*Initialize tek position variables*/
- first_vector=1; /*Always start out with first vector*/
- esc_mode=0; /*Always clear escape mode*/
- SetDrPt(tekwindow->RPort,0xffff); /*Start with solid draw pattern*/
- setdrawmode(JAM1,1);
- esc_mode=0; /*Start with esc_mode cleared*/
- set_tekmode(TEK_ALPHA); /*Start in alpha mode -oo-*/
- bypassmode=0; /*Start with bypass mode off*/
- xscr=tekwindow->BorderLeft;
- yscr=tekwindow->BorderTop+tekfont->tf_Baseline+1;
- Safe_Move(tekwindow->RPort,xscr,yscr); /*Home*/
- scrtotek();
- }
-
- /*****************************************************************************/
- /* setdrawmode() -- changes drawing mode for screen */
- /*****************************************************************************/
-
- void setdrawmode(ULONG mode,WORD noerase)
- { struct DrawInfo *di;
-
- if (di=GetScreenDrawInfo(tekwindow->WScreen))
- { if (noerase) SetAPen(tekwindow->RPort,di->dri_Pens[TEXTPEN]);
- else SetAPen(tekwindow->RPort,di->dri_Pens[BACKGROUNDPEN]);
- FreeScreenDrawInfo(tekwindow->WScreen,di);
- }
- else
- { if (noerase) SetAPen(tekwindow->RPort,1);
- else SetAPen(tekwindow->RPort,0);
- }
- SetDrMd(tekwindow->RPort,mode);
- }
-
- /*****************************************************************************/
- /* gin_mode_toggle() -- turn on/off GIN cursor */
- /*****************************************************************************/
-
- /**** NOTE : deal with setting the checkmark in the menu!!!! *****/
- /**** Also deal with setting the pointer to crosshairs ****/
-
- UWORD __chip Crosshairs[] = /*Done by hand*/
- { 0x0000,0x0000, /* Two system reserved words */
-
- 0x0000,0x0000,
- 0x0000,0x0100,
- 0x7efc,0x0100,
- 0x4004,0x0100,
- 0x4004,0x0100,
- 0x4004,0x0100,
- 0x4004,0x0100,
- 0x4004,0x0100,
- 0x0100,0xfffe,
- 0x4004,0x0100,
- 0x4004,0x0100,
- 0x4004,0x0100,
- 0x4004,0x0100,
- 0x4004,0x0100,
- 0x7efc,0x0100,
- 0x0000,0x0100,
-
- 0x0000,0x0000 /* Two more system reserved words */
- };
-
- void gin_mode_toggle(struct MenuItem *menu)
- { static int lasttekmode=TEK_ALPHA,lastbuffermode;
- struct MenuItem *item;
-
- if (menu) item=menu;
- else item=ItemAddress(menuStrip,CURSOR_MENUNUM);
- if ( (menu && (item->Flags&CHECKED)) || ((!menu) && (mode!=TEK_GIN)) )
- { lasttekmode=mode;
- lastbuffermode=buffermode;
- buffermode=0;
- set_tekmode(TEK_GIN);
- bypassmode=1;
- if (fullcursor)
- ModifyIDCMP(tekwindow,tekwindow->IDCMPFlags |
- IDCMP_MOUSEMOVE|IDCMP_MOUSEBUTTONS);
- else ModifyIDCMP(tekwindow,tekwindow->IDCMPFlags|IDCMP_MOUSEBUTTONS);
- SetPointer(tekwindow,Crosshairs,16,16,-8,-8);
- item->Flags|=CHECKED;
- ResetMenuStrip(tekwindow,menuStrip);
- }
- else
- { set_tekmode(lasttekmode);
- /*set_tekmode(TEK_ALPHA);*/
- lasttekmode=TEK_ALPHA;
- buffermode=lastbuffermode;
- bypassmode=0;
- ModifyIDCMP(tekwindow,tekwindow->IDCMPFlags &
- ~(IDCMP_MOUSEMOVE|IDCMP_MOUSEBUTTONS));
- ClearPointer(tekwindow);
- item->Flags &= ~CHECKED;
- ResetMenuStrip(tekwindow,menuStrip);
- }
- }
-
- /*****************************************************************************/
- /* ginmouse() -- deal with GIN mouse events */
- /*****************************************************************************/
-
- void ginmouse(struct IntuiMessage *msg)
- { WORD xscr,yscr,xgin,ygin;
-
- if (msg->Class==MOUSEMOVE)
- { /* Deal with moving big crosshairs if necessary */
- }
- else if (msg->Class==MOUSEBUTTONS)
- { if (msg->Code==SELECTDOWN)
- { Forbid();
- xscr=tekwindow->MouseX;
- yscr=tekwindow->MouseY;
- Permit();
- xgin=((xscr-tekwindow->BorderLeft)*tekwidth)/winw;
- ygin=(-(yscr-tekwindow->BorderTop-winh)*tekheight)/winh;
- sendreport(xgin,ygin,' ');
- gin_mode_toggle(NULL); /*quit GIN mode*/
- }
- }
- ReplyMsg((struct Message *)msg);
- }
-
- /*****************************************************************************/
- /* ginkeys() -- deal with GIN RAWKEY events */
- /*****************************************************************************/
-
- void ginkeys(struct IntuiMessage *msg)
- { struct InputEvent ie;
- char buf[4];
- WORD xscr,yscr,xgin,ygin;
-
- if (msg->Code & IECODE_UP_PREFIX) return;
- ie.ie_Code=msg->Code;
- ie.ie_NextEvent=NULL;
- ie.ie_SubClass=0;
- ie.ie_Class=IECLASS_RAWKEY;
- ie.ie_Qualifier=msg->Qualifier;
- ie.ie_position.ie_addr=*((APTR *)msg->IAddress);
- RawKeyConvert(&ie,buf,4,np.national ? used_map : default_map);
-
- /*** Send report with mouse x,y tek position */
- Forbid();
- xscr=tekwindow->MouseX;
- yscr=tekwindow->MouseY;
- Permit();
- xgin=((xscr-tekwindow->BorderLeft)*tekwidth)/winw;
- ygin=(-(yscr-tekwindow->BorderTop-winh)*tekheight)/winh;
- sendreport(xgin,ygin,buf[0]);
- ReplyMsg((struct Message *)msg);
- gin_mode_toggle(NULL);
- }
-
- /*****************************************************************************/
- /* sendreport() -- Send 4010 style report to host */
- /* Pass x,y in 4014 4096-pixel coordinate system. */
- /* This routine converts it to 1024 before sending the report */
- /*****************************************************************************/
-
- void sendreport(WORD x,WORD y,char c)
- { char report[10];
- int i=-1,j;
-
- if (c) report[++i]=c;
- switch (mode) /* Set bits 2-3 of status based on mode*/
- { case TEK_POINT : report[++i]=0x01; break; /* Bit 0 always set */
- case TEK_ALPHA : report[++i]=0x05; break;
- case TEK_VECTOR : report[++i]=0x09; break;
- case TEK_GIN : break;
- default : report[++i]=0x0d; break;
- }
- report[++i]=0x20 | ( (x & 0x0f80)>>7 ); /*HiX*/
- report[++i]=0x20 | ( (x & 0x007c)>>2 ); /*LoX*/
- report[++i]=0x20 | ( (y & 0x0f80)>>7 ); /*HiY*/
- report[++i]=0x20 | ( (y & 0x007c)>>2 ); /*LoY*/
- for (j=0;j<strlen(eolstring);j++)
- report[++i]=eolstring[j];
- report[++i]='\0';
- nwrite(report,i);
- }
-
- /*****************************************************************************/
- /* redrawtek() -- redraw tek window from buffer */
- /*****************************************************************************/
-
- void redrawtek(void)
- { char *c;
-
- /* Start with a simulation of graph_clear, all but the buffer clearing*/
- SetAPen(tekwindow->RPort,0);
- RectFill(tekwindow->RPort,tekwindow->BorderLeft,tekwindow->BorderTop,
- tekwindow->Width-1-tekwindow->BorderRight,
- tekwindow->Height-1-tekwindow->BorderBottom);
- HiY=Extra=LoY=HiX=LoX=LoYorExtra=(char)0; /*Initialize tek position variables*/
- first_vector=1; /*Always start out with first vector*/
- esc_mode=0; /*Always clear escape mode*/
- SetDrPt(tekwindow->RPort,0xffff); /*Start with solid draw pattern*/
- setdrawmode(JAM1,1);
-
- buffermode=1;
- if (startbuffer>endbuffer)
- { c=tekout(startbuffer,tekbuffer+BUFFERSIZE);
- c=tekout(tekbuffer,endbuffer);
- }
- else c=tekout(startbuffer,endbuffer);
- buffermode=0;
- /* Deal with c not being equal to text+count*/
- }
-
- /********************************************************************************/
- /* tekout() -- handle characters incoming into the Tek screen */
- /* Generally, this will be called from termout (see emulate.c). It returns */
- /* a pointer to the first charcter after a return to VT100 mode, or to */
- /* endtext. This way, termout can call tekout and use it's return value for */
- /* updating its pointer into the string of characters which have been handled*/
- /********************************************************************************/
-
- /***** Meanings of esc modes:
- 0 no escape
- 1 ESC
- 2 ESC [ or CSI
- 3 ESC "
- 4 ESC [ ?
- 6 ESC %
- 7 ESC % !
- ****/
-
- char *tekout(char *text,char *endtext)
- { char *c;
- WORD xscr,yscr,xgin,ygin;
- static int esc_number=0,seq_length=0;
-
- for (c=text;c<endtext;c++)
- { if (!buffermode)
- { *endbuffer=*c;
- if (endbuffer-tekbuffer==BUFFERSIZE-1) endbuffer=tekbuffer;
- else endbuffer++;
- if (startbuffer>=endbuffer)
- { startbuffer++;
- if (startbuffer-tekbuffer==BUFFERSIZE-1) startbuffer=tekbuffer;
- }
- }
-
- if (mode==TEK_GIN) /* GIN (bypass) mode sequences */
- { switch(*c)
- { case ESC : if (esc_mode) {}
- else
- { esc_mode=1;
- esc_number=0;
- }
- break;
-
- case ENQ : if (esc_mode==1)
- { Forbid();
- xscr=tekwindow->MouseX;
- yscr=tekwindow->MouseY;
- Permit();
- xgin=((xscr-tekwindow->BorderLeft)*tekwidth)/winw;
- ygin=(-(yscr-tekwindow->BorderTop-winh)*tekheight)/winh;
- sendreport(xgin,ygin,'\0');
- gin_mode_toggle(NULL); /*quit GIN mode*/
- }
- break;
-
- case LF :
- case CR : gin_mode_toggle(NULL); /*quit GIN mode, don't*/
- break; /* change esc_mode */
-
- case BS :
- case VT :
- case HT : if (esc_mode==0) gin_mode_toggle(NULL);
- else esc_mode=0;
- break;
-
- case BEL : DisplayBeep(tekwindow->WScreen);
- esc_mode=0;
- gin_mode_toggle(NULL);
- break;
-
- case CAN :
- case SUB : esc_mode=0; /* -oo- These just set bypass or GIN */
- break;
-
- case US : esc_mode=0;
- gin_mode_toggle(NULL);
- set_tekmode(TEK_ALPHA);
- break;
-
- case FF : if (esc_mode==1)
- { gin_mode_toggle(NULL);
- graph_clear();
- }
- break;
- }
- } /*End of GIN mode handling */
-
- else if (!esc_mode && (*c>=0x20)) /*If not a CTRL char or ESC sequence...*/
- { if ((mode==TEK_VECTOR)||(mode==TEK_POINT)||(mode==TEK_BLOCK))
- { if (decode_integer(*c)) /*Non-zero result indicates LoX rec.*/
- { tekx=((short)(HiX & 0x1f)<<7) | /*Build new X tek position*/
- ((short)(LoX & 0x1f)<<2) |
- ((short)(Extra & 0x03));
- teky=((short)(HiY & 0x1f)<<7) | /*Build new Y tek position*/
- ((short)(LoY & 0x1f)<<2) |
- ((short)(Extra & 0x0c)>>2);
- xscr=tekwindow->BorderLeft+(tekx*winw)/tekwidth; /*Screen position*/
- yscr=tekwindow->BorderTop+winh-(teky*winh)/tekheight;
- if (mode==TEK_POINT)
- { WritePixel(tekwindow->RPort,xscr,yscr); /*Does check bounds*/
- Safe_Move(tekwindow->RPort,xscr,yscr);
- }
- else
- { if (first_vector)
- { Safe_Move(tekwindow->RPort,xscr,yscr);
- first_vector=0;
- }
- else
- { if (mode==TEK_VECTOR)
- Safe_Draw(tekwindow->RPort,xscr,yscr);
- else
- Safe_Rect(tekwindow->RPort,xscr,yscr);
- }
- }
- }
- } /*End of TEK_VECTOR and TEK_POINT handling*/
- else if (mode==TEK_ALPHA)
- { if (tekwindow->RPort->cp_x >
- tekwindow->Width-tekwindow->BorderRight-tekfont->tf_XSize)
- { xscr=tekwindow->BorderLeft;
- yscr=tekwindow->RPort->cp_y+tekfont->tf_YSize+1;
- if ( (yscr+tekfont->tf_YSize-tekfont->tf_Baseline) >
- tekwindow->Height-tekwindow->BorderBottom )
- yscr=tekwindow->BorderTop+tekfont->tf_Baseline+1;
- Safe_Move(tekwindow->RPort,xscr,yscr);
- }
- Text(tekwindow->RPort,c,1); /*Write the character*/
- } /*End of TEK_ALPHA handling*/
- else if (mode==TEK_INCR)
- { if (*c==' ') incr_pen_down=0;
- else if (*c=='P') incr_pen_down=1;
- else
- { switch(*c)
- { case 'D' : teky+=1; break;
- case 'E' : teky+=1; tekx+=1; break;
- case 'A' : tekx+=1; break;
- case 'I' : teky-=1; tekx+=1; break;
- case 'H' : teky-=1;
- case 'J' : teky-=1; tekx-=1; break;
- case 'B' : tekx-=1;
- case 'F' : tekx-=1; teky+=1; break;
- }
- xscr=tekwindow->BorderLeft+(tekx*winw)/tekwidth; /*Screen position*/
- yscr=tekwindow->BorderTop+winh-(teky*winh)/tekheight;
- Safe_Draw(tekwindow->RPort,xscr,yscr);
- }
- }
- }
-
-
- /* NOTE -- ESC sequences will be interpreted in all modes, even if they
- aren't supposed to be. Fix this later?*/
- /* GIN mode is a special case, above */
-
- else /*Handling of ESC sequences and CTRL codes*/
- { ++seq_length;
- if ((esc_mode==3 || esc_mode==4) && *c>='0' && *c<='9')
- esc_number=10*esc_number+ *c-'0';
- else switch(*c) /* *c is a control character of some sort*/
- { /* Vector & Point mode sequences */
- case ESC : if (esc_mode) {} /* ESC ESC == ESC */
- else
- { esc_mode=seq_length=1;
- esc_number=0;
- }
- break;
-
- case STX : if (esc_mode==1 && mode==TEK_VECTOR)
- { set_tekmode(TEK_BLOCK);
- first_vector=1;
- }
- esc_mode=0;
- break;
-
- case ETX : if (esc_mode==1 && mode==TEK_BLOCK)
- { set_tekmode(TEK_VECTOR);
- first_vector=1;
- }
- esc_mode=0;
- break;
-
- case SOH : if (esc_mode==1) setdrawmode(JAM1,1);
- esc_mode=0; /*Writing mode = draw*/
- break;
-
- case DLE : if (esc_mode==1) setdrawmode(JAM1,0);
- esc_mode=0; /*Writing mode = erase*/
- break;
-
- case NAK : if (esc_mode==1) setdrawmode(INVERSVID,1);
- esc_mode=0; /*Writing mode=invert*/
- break;
-
- case EM : if (esc_mode==1) setdrawmode(JAM2,1);
- esc_mode=0; /*Writing mode=replace*/
- break;
-
- case BEL : DisplayBeep(tekwindow->WScreen);
- esc_mode=0;
- break;
-
- case CR : if (mode!=TEK_ALPHA) mode=TEK_ALPHA;
- else
- { Safe_Move(tekwindow->RPort,tekwindow->BorderLeft,
- tekwindow->RPort->cp_y);
- scrtotek();
- }
- break;
-
- case FF : if (esc_mode==1)
- { graph_clear(); /*More??*/
- if (mode==TEK_INCR) set_tekmode(TEK_ALPHA);
- }
- esc_mode=0;
- break;
-
- case CAN : if (esc_mode==0)
- { tek_vt100(); /*Switch back to vt100 mode*/
- if (!buffermode)
- { endbuffer--; /*Kill vt100 esc seq from buffer*/
- ENDCHECK;
- }
- return(++c); /*Return position to keep going*/
- }
- else if (esc_mode==1)
- { /*set bypass condition -oo- !!!!!!!!!*/
- esc_mode=0;
- if (mode==TEK_ALPHA) graph_clear();
- }
- else esc_mode=0;
- break;
-
-
- case SUB : if (esc_mode==1)
- { gin_mode_toggle(NULL);
- if (!buffermode)
- { endbuffer-=seq_length; /*No buffering GIN mode*/
- ENDCHECK;
- }
- esc_mode=esc_number=0;
- }
- else esc_mode=0;
- break;
-
- case FS : set_tekmode(TEK_POINT);
- esc_mode=0;
- break;
-
- case GS : set_tekmode(TEK_VECTOR);
- esc_mode=0;
- first_vector=1;
- break;
-
- case RS : set_tekmode(TEK_INCR);
- esc_mode=0;
- break;
-
- case US : set_tekmode(TEK_ALPHA);
- esc_mode=0;
- break;
-
- case '`' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xffff);
- SetAPen(tekwindow->RPort,1);
- esc_mode=0;
- }
- break;
-
- case 'a' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xaaaa);
- SetAPen(tekwindow->RPort,1);
- }
- esc_mode=0;
- break;
-
- case 'b' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xfafa);
- SetAPen(tekwindow->RPort,1);
- }
- esc_mode=0;
- break;
-
- case 'c' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xeeee);
- SetAPen(tekwindow->RPort,1);
- }
- esc_mode=0;
- break;
-
- case 'd' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xfcfc);
- SetAPen(tekwindow->RPort,1);
- }
- esc_mode=0;
- break;
-
- case 'e' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xff55);
- SetAPen(tekwindow->RPort,1);
- }
- esc_mode=0;
- break;
-
- case 'f' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xff6c);
- SetAPen(tekwindow->RPort,1);
- }
- esc_mode=0;
- break;
-
- case 'g' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xf0f0);
- SetAPen(tekwindow->RPort,1);
- }
- else if (esc_mode==3) /*From SuperMode*/
- { tek_vt100();
- if (!buffermode)
- { endbuffer-=seq_length; /*Remove to vt100 seq from buf*/
- ENDCHECK;
- }
- esc_mode=0;
- return(++c);
- }
- /* Note -- I ought to check to make sure there was a 0*/
- esc_mode=0;
- break;
-
- case 'h' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xffff);
- SetAPen(tekwindow->RPort,2);
- }
- else if (esc_mode==4) /*ESC [ ? <number> h*/
- { if (esc_number==38) {} /*Switch to tek-- do nil*/
- }
- esc_mode=0;
- break;
-
- case 'i' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xaaaa);
- SetAPen(tekwindow->RPort,2);
- }
- esc_mode=0;
- break;
-
- case 'j' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xfafa);
- SetAPen(tekwindow->RPort,2);
- }
- esc_mode=0;
- break;
-
- case 'k' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xeeee);
- SetAPen(tekwindow->RPort,2);
- }
- esc_mode=0;
- break;
-
- case 'l' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xfcfc);
- SetAPen(tekwindow->RPort,2);
- }
- else if (esc_mode==4) /*ESC [ ? <number> l*/
- { if (esc_number==38) /*Switch to vt100*/
- { esc_mode=0;
- tek_vt100();
- if (!buffermode)
- { endbuffer-=seq_length; /*Remove esc seq from buffer*/
- ENDCHECK;
- }
- return(++c);
- }
- }
- esc_mode=0;
- break;
-
- case 'm' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xff55);
- SetAPen(tekwindow->RPort,2);
- }
- esc_mode=0;
- break;
-
- case 'n' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xff6c);
- SetAPen(tekwindow->RPort,2);
- }
- esc_mode=0;
- break;
-
- case 'o' : if (esc_mode==1)
- { SetDrPt(tekwindow->RPort,0xf0f0);
- SetAPen(tekwindow->RPort,2);
- }
- esc_mode=0;
- break;
-
- case '?' : if (esc_mode==1)
- { LoY=0x7f; /*DEL character replacement*/
- esc_mode=0;
- }
- else if (esc_mode==2) /*<CSI>*/
- esc_mode=4;
- else esc_mode=0;
- break;
-
- /* End of Vector Mode sequences*/
- /* Alpha mode sequences */
- /* See Vector mode for ESC,BEL,ESC/FF,ESC/SUB,FS,GS,RS,CR*/
-
- case ENQ : /* -oo- report terminal status */
- if (esc_mode) esc_mode=0;
- break;
-
- case DEL: if (esc_mode) break;
- /* Otherwise same as BS */
- case BS : /* Move one space left */
- if (esc_mode) esc_mode=0;
- if (mode==TEK_ALPHA)
- { if (tekwindow->RPort->cp_x < tekfont->tf_XSize)
- xscr=tekwindow->BorderLeft;
- else xscr=tekwindow->RPort->cp_x-tekfont->tf_XSize;
- Safe_Move(tekwindow->RPort,xscr,tekwindow->RPort->cp_y);
- scrtotek();
- }
- break;
-
- case HT : /*Horiz tab*/
- if (esc_mode) esc_mode=0;
- break;
-
- case LF : /*CRLF*/
- if ( esc_mode==0 && mode==TEK_ALPHA )
- { xscr=tekwindow->BorderLeft;
- yscr=tekwindow->RPort->cp_y+tekfont->tf_YSize+1;
- if ( (yscr+tekfont->tf_YSize-tekfont->tf_Baseline) >
- tekwindow->Height-tekwindow->BorderBottom )
- yscr=tekwindow->BorderTop+tekfont->tf_Baseline+1;
- Safe_Move(tekwindow->RPort,xscr,yscr);
- scrtotek();
- }
- /* esc_mode=0; */ /* ESC LF == ESC */
- break;
-
- case VT : /*Move one line up*/
- if (esc_mode) esc_mode=0;
- break;
-
- /* End of Alpha mode sequences*/
- /* Incremental Plot Mode sequences*/
- /* End of Incremental Plot Mode sequences*/
- /* SuperMode sequences -- this needs some work!*/
-
- case '"' : if (esc_mode==1) esc_mode=3;
- else esc_mode=0;
- break;
-
- case '[' : if (esc_mode==1) esc_mode=2; /*<CSI>*/
- else esc_mode=0;
- break;
-
- case '%' : if (esc_mode==1) esc_mode=6;
- else esc_mode=0;
- break;
-
- case '!' : if (esc_mode==6) esc_mode=7;
- else esc_mode=0;
- break;
-
- case '0' : if (esc_mode==7) vt100_tek();
- esc_mode=0;
- break;
-
- case '1' : if (esc_mode==7)
- { tek_vt100();
- if (!buffermode)
- { endbuffer-=seq_length; /*Remove esc seq from buffer*/
- ENDCHECK;
- }
- }
- esc_mode=0;
- break;
-
- case '2' : if (esc_mode==1)
- { tek_vt100();
- if (!buffermode)
- { endbuffer-=seq_length;
- ENDCHECK;
- }
- }
- esc_mode=0;
- break;
-
- /* case g h l ? handled above */
-
- /* End of SuperMode sequences */
-
- default : if (esc_mode) esc_mode=0;
- break;
- } /*End of switch over escaped characters*/
- }
- } /*End of the massive for loop over input characters*/
- return(c); /*Should be text+count*/
- }
-
- /**********************************************************************/
- /* decode_integer() Works on decoding a Tek integer */
- /* Returns 1 if LoX was received, and terminal should act on the */
- /* integer that has just been built. */
- /**********************************************************************/
-
- int decode_integer(char c)
- { char tagbits;
- int rv;
-
- rv=0;
- tagbits=c & 0x60;
- if (tagbits==0x20) /*HiY or HiX*/
- { if (LastTag==0x60) /*Last was LoY, this is HiX*/
- { HiX=c;
- if (LoYorExtra)
- { LoY=LoYorExtra;
- LoYorExtra=0;
- }
- }
- else HiY=c;
- }
- else if (tagbits==0x60) /*LoY or Extra*/
- { if (LastTag==0x60) /*Last was Extra, this is LoY*/
-
- { Extra=LoYorExtra;
- LoYorExtra=0;
- LoY=c;
- }
- else /*Unknown if LoY or Extra*/
- LoYorExtra=c;
- }
- else if (tagbits==0x40) /*LoX, draw the vector whatever*/
- { if (LastTag==0x60 && LoYorExtra) /* last was LoY */
- LoY=LoYorExtra;
- LoX=c;
- rv=1;
- }
- LastTag=tagbits;
- return(rv);
- }
-
- /********************************************************************************/
- /* Draw to tekwindow, first checking to make sure we don't go outside boudries */
- /* Note: because coordinates are represented with 12-bit unsigned integers, */
- /* it is impossible for x to be out of bounds, and y can only be too large */
- /* (assuming a y resolution of 3025 rather than 4096) */
- /********************************************************************************/
-
- void Safe_Move(struct RastPort *rp,WORD x,WORD y)
- {
- lastx=x; lasty=y;
- if (!(lyok=(y<=maxy))) y=maxy;
- Move(rp,x,y);
- }
-
- void Safe_Draw(struct RastPort *rp,WORD x,WORD y)
- { WORD x0;
-
- if (y<=maxy)
- { if (lyok) Draw(rp,x,y); /*All clear*/
- else
- { x0=x + (maxy-y) * (lastx-x) / (lasty-y);
- Move(rp,x0,maxy);
- Draw(rp,x,y);
- }
- }
- else
- { if (!lyok) Safe_Move(rp,x,y); /*Won't draw anyway*/
- else
- { x0=lastx + (maxy-lasty) * (x-lastx) / (y-lasty);
- Draw(rp,x0,maxy);
- }
- }
- lastx=x; lyok=((lasty=y)<=maxy);
- }
-
- void Safe_Rect(struct RastPort *rp,WORD x,WORD y)
- { WORD xmin,xmax,ymin,ymax;
-
- if (y<=maxy) ymax=y; else ymax=maxy;
- if (lyok) ymin=lasty; else ymin=maxy;
- if (ymin>ymax) { xmin=ymin; ymin=ymax; ymax=xmin; }
- if (lastx>x) { xmax=lastx; xmin=x; }
- else { xmin=lastx; xmax=x; }
- RectFill(rp,xmin,ymin,xmax,ymax);
- lastx=x; lyok=((lasty=y)<=maxy);
- }
-
- /*****************************************************************************/
- /* Convert screen coords in lastx,lasty to tek coords in tekx,teky */
- /*****************************************************************************/
-
- void scrtotek()
- {
- tekx=((lastx-tekwindow->BorderLeft)*tekwidth) / winw;
- teky=((tekwindow->BorderTop+winh-lasty)*tekheight) / winh;
- }
-
-
- /********************************************************************************/
- /* Accept IDCMP events from tek window */
- /********************************************************************************/
-
- void tekpoll(void)
- {
- struct IntuiMessage *msg;
-
- while (tekwindow && (msg=(struct IntuiMessage *)GetMsg(tekwindow->UserPort)))
- { switch(msg->Class)
- { case RAWKEY : if (bypassmode) ginkeys(msg);
- else dokeys(msg); /* Send to vt100 key handler */
- break;
- case CLOSEWINDOW : ReplyMsg((struct Message *)msg);
- closetekwin();
- tekmode=0;
- break;
- case NEWSIZE : calctekwinsize();
- ReplyMsg((struct Message *)msg);
- /* graph_clear();*/
- redrawtek();
- break;
- case MENUPICK : tekmenu(msg);
- break;
-
- case MOUSEMOVE:
- case MOUSEBUTTONS: if (mode==TEK_GIN) ginmouse(msg);
- else ReplyMsg((struct Message *)msg);
- break;
- default: ReplyMsg((struct Message *)msg);
- }
- }
- }
-
- /*****************************************************************************/
- /* Deal with menu events */
- /*****************************************************************************/
-
- static int close_it=0;
-
- void menu_close(void)
- { close_it=1;
- }
-
- void tekmenu(struct IntuiMessage *msg)
- { UWORD Code; /*,menuNum,itemNum,subNum;*/
- struct MenuItem *item;
- void (*func)(struct MenuItem *);
-
- close_it=0;
- Code=msg->Code;
- while ((Code!=MENUNULL) && (!close_it))
- { item=ItemAddress(menuStrip,Code);
- /***
- menuNum=MENUNUM(Code);
- itemNum=ITEMNUM(Code);
- subNum=SUBNUM(Code);
- ***/
- func=(void(*)())GTMENUITEM_USERDATA(item);
- (*func)(item);
- Code=item->NextSelect;
- }
- ReplyMsg((struct Message *)msg);
- if (close_it)
- { closetekwin();
- tekmode=0;
- }
- }
-
- /*****************************************************************************/
- /* Check state of activatewindow and frontwindow menuitems */
- /*****************************************************************************/
-
- void chk_active(struct MenuItem *item)
- {
- activateonswitch = item->Flags & CHECKED;
- }
-
- void chk_front(struct MenuItem *item)
- {
- forwardonswitch = item->Flags & CHECKED;
- }
-
-
-
- #endif /*end of ifdef TEKTRONICS*/
-